package tq.com.crop;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;


import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import tq.com.systools.R;

/**
 * Author:    ZhuWenWu
 * Version    V1.0
 * Date:      15/8/18 22:57
 * Description: 图片裁剪页面
 * Modification  History:
 * Date         	Author        		Version        	Description
 * -----------------------------------------------------------------------------------
 * 15/8/18      ZhuWenWu            1.0                    1.0
 * Why & What is modified:
 */
public class CropImageActivity extends Activity {
    CropImageView mCropImageView;
    ImageView mTvCrop;
    TextView tvCancel;

    private boolean rotate;
    private Bitmap mBitmap;
    private Uri mOutputPath = null;

    public static class CropParam {
        public int mAspectX = 0;
        public int mAspectY = 0;
        public int mOutputX = 0;
        public int mOutputY = 0;
        public int mMaxOutputX = 0;
        public int mMaxOutputY = 0;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_crop_image);

        mCropImageView = findViewById(R.id.civ_window);
        mTvCrop = findViewById(R.id.tv_crop);
        tvCancel = findViewById(R.id.tv_cancel);

        findViewById(R.id.tv_crop).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onClickCrop(v);
            }
        });

        findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onCancel();
            }
        });
        setUpViewComponent();
    }

    private void setUpViewComponent() {
        Intent intent = getIntent();
        boolean isSendPicture = intent.getBooleanExtra("isSendPicture", false);
//        mTvCrop.setText(isSendPicture ? R.string.send : R.string.crop);
        rotate = intent.getBooleanExtra(CropIntent.Rotate, false);

        Bundle extras = intent.getExtras();
        if (extras == null) {
            setResult(RESULT_CANCELED);
            return;
        }
        Uri mInputPath = intent.getData();
        mOutputPath = extras.getParcelable(MediaStore.EXTRA_OUTPUT);
        if (mInputPath == null || mOutputPath == null) {
            setResult(RESULT_CANCELED);
            finish();
            return;
        }

        mBitmap = loadBitmapWithInSample(mInputPath);
        if (mBitmap == null) {
            setResult(RESULT_CANCELED);
            finish();
            return;
        }
        if(rotate){
            mBitmap = rotate(90, mBitmap);
            mTvCrop.setRotation(90);
            tvCancel.setRotation(90);
        }
        mCropImageView.initialize(mBitmap, getCropParam(intent));
    }

    @Override
    protected void onDestroy() {
        if (mBitmap != null) {
            mBitmap.recycle();
        }
        mCropImageView.destroy();
        super.onDestroy();
    }

    void onClickRotate(View v) {
//        LogUtils.d(TAG, "onClickRotate --> ");
        mCropImageView.rotate();
        mCropImageView.invalidate();
    }

    public void onClickReset(View v) {
//        LogUtils.d(TAG, "onClickReset --> ");
        mCropImageView.reset();
    }

    public void onClickCrop(View v) {
//        LogUtils.d(TAG, "onClickCrop --> ");
        mCropImageView.crop();
        Bitmap bitmap = mCropImageView.getCropBitmap();
        if(rotate){
            bitmap = rotate(-90, bitmap);
        }

        new SaveImageTask().execute(bitmap);
    }

    public void onCancel() {
        setResult(RESULT_CANCELED);
        finish();
    }

    private Bitmap rotate(int degree, Bitmap bitmap){
        Matrix m = new Matrix();
        m.setRotate(degree, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
        Bitmap bm1 = null;

        try {
            bm1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
        } catch (OutOfMemoryError ex) {
            return null;
        }
        return bm1;
    }

    private class SaveImageTask extends AsyncTask<Bitmap, Void, Boolean> {
        private SaveImageTask() {
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onPostExecute(Boolean result) {
            setResult(RESULT_OK, new Intent().putExtra(MediaStore.EXTRA_OUTPUT, mOutputPath));
            finish();
        }

        @Override
        protected Boolean doInBackground(Bitmap... params) {
            OutputStream outputStream = null;
            try {
                outputStream = getContentResolver().openOutputStream(mOutputPath);
                if (outputStream != null) {
                    params[0].compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                closeSilently(outputStream);
            }

            return Boolean.TRUE;
        }

    }

    protected Bitmap loadBitmapWithInSample(Uri uri) {
        final int MAX_VIEW_SIZE = 1024;
        InputStream in;
        try {
            in = getContentResolver().openInputStream(uri);
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(in, null, o);
            if (in != null) {
                in.close();
            }

            int scale = 1;
            if (o.outHeight > MAX_VIEW_SIZE || o.outWidth > MAX_VIEW_SIZE) {
                scale = (int) Math.pow(2, (int) Math.round(Math.log(MAX_VIEW_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
            }

            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            in = getContentResolver().openInputStream(uri);
            Bitmap b = BitmapFactory.decodeStream(in, null, o2);
            if (in != null) {
                in.close();
            }

            return b;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    protected static void closeSilently(Closeable c) {
        if (c == null) return;
        try {
            c.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    public static CropParam getCropParam(Intent intent) {
        CropParam params = new CropParam();
        Bundle extras = intent.getExtras();
        if (extras != null) {
            if (extras.containsKey(CropIntent.ASPECT_X) && extras.containsKey(CropIntent.ASPECT_Y)) {
                params.mAspectX = extras.getInt(CropIntent.ASPECT_X);
                params.mAspectY = extras.getInt(CropIntent.ASPECT_Y);
            }
            if (extras.containsKey(CropIntent.OUTPUT_X) && extras.containsKey(CropIntent.OUTPUT_Y)) {
                params.mOutputX = extras.getInt(CropIntent.OUTPUT_X);
                params.mOutputY = extras.getInt(CropIntent.OUTPUT_Y);
            }
            if (extras.containsKey(CropIntent.MAX_OUTPUT_X) && extras.containsKey(CropIntent.MAX_OUTPUT_Y)) {
                params.mMaxOutputX = extras.getInt(CropIntent.MAX_OUTPUT_X);
                params.mMaxOutputY = extras.getInt(CropIntent.MAX_OUTPUT_Y);
            }
        }
        return params;
    }

    @Override
    public void onBackPressed() {
        setResult(RESULT_CANCELED);
        finish();
    }

    public void onResume() {
        super.onResume();
    }

    public void onPause() {
        super.onPause();
    }
}
